﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Gueei.Gallery.Core.Entities;
using Gueei.Gallery.Core.Repositories;
using Newtonsoft.Json;

namespace Gueei.Gallery.JsonRepositories
{
	public class JsonAlbumRepository:IAlbumRepository
	{
		private readonly List<AlbumSaveEntry> _albums;
		private IImageRepository ImageRepo { get; set; }

		public JsonAlbumRepository(string jsonDir, IImageRepository imageRepo)
		{
			ImageRepo = imageRepo;
			Directory.CreateDirectory(jsonDir);
			JsonFilePath = Path.Combine(jsonDir, "albums.js");
			if (File.Exists(JsonFilePath))
			{
				try
				{
					string json = "";
					using (var fs = new StreamReader(JsonFilePath))
					{
						json = fs.ReadToEnd();
					}
					_albums = JsonConvert.DeserializeObject<List<AlbumSaveEntry>>(json);
				}
				catch
				{
					_albums = new List<AlbumSaveEntry>();
				}
			}
			else
			{
				_albums = new List<AlbumSaveEntry>();
			}
		}
		protected string JsonFilePath
		{
			get;
			set;
		}
		public bool AlbumExists(Guid id)
		{
			return (_albums.Where(a => a.Id.Equals(id)).FirstOrDefault() != null);
		}

		public Core.Entities.Album GetAlbumById(Guid id)
		{
			if (!AlbumExists(id))
				return null;
			return _albums.Where(a => a.Id.Equals(id)).First().GetAlbum(ImageRepo);
		}

		public IQueryable<Core.Entities.Album> GetAlbumsByImageId(Guid id)
		{
			return _albums.Where(a => a.ImageIds.Contains(id)).Select(a => a.GetAlbum(ImageRepo)).AsQueryable();
		}

		public IQueryable<Core.Entities.Album> GetAlbumsByName(string name)
		{
			return _albums.Where(a => a.Name.Equals(name)).Select(a=>a.GetAlbum(ImageRepo)).AsQueryable();
		}

		public IQueryable<Core.Entities.Album> GetAllAlbums()
		{
			return _albums.Select(a => a.GetAlbum(ImageRepo)).AsQueryable();
		}

		public Core.Entities.Album CreateAlbum(string name, ISet<Image> images, ISet<Tag> tags)
		{
			var newAlbum = new AlbumSaveEntry
			               	{
			               		Name = name, 
								ImageIds = images.Select(i => i.Id).ToList(), 
								Id = Guid.NewGuid(),
								TagIds = tags.Select(t=>t.Id).ToList()
			               	};
			_albums.Add(newAlbum);

			Save();
			return newAlbum.GetAlbum(ImageRepo);
		}

		private void Save()
		{
			var json = JsonConvert.SerializeObject(_albums);
			using (var fs = new StreamWriter(JsonFilePath))
			{
				fs.WriteLine(json);
			}			
		}

		private class AlbumSaveEntry
		{
			public Guid Id { get; set; }
			public Guid CoverImageId { get; set; }
			public string Name { get; set; }
			public IList<Guid> ImageIds { get; set; }
			public IList<Guid> TagIds { get; set; }

			public Album GetAlbum(IImageRepository imageRepo)
			{
				return new Album
				       	{
				       		Id = Id,
				       		Name = Name,
							CoverImage = imageRepo.GetImage(CoverImageId),
				       		Images = imageRepo.GetImages().Where(i => ImageIds.Contains(i.Id)).ToList()
				       	};
			}

			public void UpdateWithAlbum(Album album)
			{
				this.CoverImageId = album.CoverImage.Id;
				this.Name = album.Name;
				this.ImageIds = album.Images.Select(i => i.Id).ToList();
				this.TagIds = album.Tags.Select(t => t.Id).ToList();
			}
		}


		public Album SaveAlbum(Album album)
		{
			_albums.Where(a => a.Id == album.Id).First().UpdateWithAlbum(album);
			Save();
			return album;
		}
	}
}
